using Godot;
using Godot.Collections;
using Godot.NativeInterop;
using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.XPath;

public partial class Player : Characters
{
	private AnimatedSprite2D _animatedSprite2D;
	//private Movement _movement;
	private AnimationPlay _animationPlay;
	private Marker2D _hitboxPosition;
	private Area2D _hurtbox;
	private Camera2D _camera;
	private CEquipment _cEquipment;
	private SkillManager _skillManager;
	private TaskManager _taskManager;
	private CInventory _cInventory;
	private Area2D _floorCheck;
	public Item itemLeftHand;
	public Item itemRightHand;
	
	public Godot.Collections.Array<Interactable> interacting_with;
	
	// Called when the node enters the scene tree for the first time.
	public override void Initialize()
    {
        base.Initialize();
		DataInit();
		_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
		_movement = GetNode<Movement>("Movement");
		_movement.Initialize();
		//_stateMachine = GetNode<StateMachine>("StateMachine");
		//_stateMachine.Initialize();
		_animationPlay = GetNode<AnimationPlay>("AnimationPlay");
		_animationPlay.Initialize();
		_hitboxPosition = GetNode<Marker2D>("Hitposition");
        _hitboxPosition.Rotation = 0;
        _hurtbox = GetNode<Area2D>("Hurtbox");
		_timer = GetNode<Timer>("Timer");
		_timer.Timeout += OnTimerOut;
		interacting_with = new Array<Interactable>();
		_camera = this.GetNode<Camera2D>("Camera2D");
		_skillManager = this.GetNode<SkillManager>("SkillManager");
		_taskManager = this.GetNode<TaskManager>("TaskManager");
		_taskManager.Initialize();
		_cInventory = this.GetNode<CInventory>("CInventory");
		_cEquipment = this.GetNode<CEquipment>("CEquipment");
		_floorCheck = GetNode<Area2D>("FloorCheck");
		InitializeByLoadData();
    }

	// Called every frame. 'delta' is the elapsed time since the previous frame.

	public override void tickProcess(double delta)
	{
		
		_camera.Enabled = true;
		_camera.ResetSmoothing();
		//action = "idle";
		Vector2I _moveDirection = MoveInput();

		switch ((State)_stateMachine.current_state)
		{
			case State.IDLE:
			{
				break;
			}
			case State.RUN:
			{
                _movement.Move(_moveDirection,delta);
			    _movement.Update (delta);
				break;
			}
            case State.SKILL:
            {
                break;
            }
		}

		if(_characterData.health <= 0)
       	{
			var UIControl = GetNode<UIControl>("/root/UIControl");
			UIControl.GetGuiViewManager().open_view("UiGameOver");
       	}
		var _mouseposition= GetGlobalMousePosition();
		var direction = MouseDirection(_mouseposition);
		var direction_player = (90-direction) / 180 * Math.PI;//鼠标相对于玩家的方向，弧度，向右、下为正方向
		_hitboxPosition.Position = new Vector2((float)Math.Cos(direction_player) * 10,(float)Math.Sin(direction_player) * 10);//旋转hitbox指向鼠标位置
		_hitboxPosition.Rotation = (float)direction_player;
		//_sight.Rotation = (float)direction_player;


		var movedirection = MoveDirection();
		if(action =="idle")
		{
			movedirection = direction;
		}
		var directionToplayer = (90-movedirection) / 180 * Math.PI;
		_sight.Rotation = (float)directionToplayer;
		//_animationPlay.Player_Animation(movedirection,action,8.0f);//通用动画播放，可根据父节点选择角色，根据方向选择方向，还需要优化
		if(interacting_with.Count!=0&&Input.IsActionJustReleased("interact"))
		{
			interacting_with[interacting_with.Count-1].Interact();
		}
		//GD.Print("旋转角度：",_sight.Rotation/3.15*180);
	}

	public double MouseDirection(Vector2 _mouseposition)  //加算鼠标位置与玩家的角度，结果用°表示，范围0~360，逆时针，正下方为0
	{
		Vector2 globalPosition = GlobalPosition;
		double x = _mouseposition.X - globalPosition.X;
		double y = _mouseposition.Y - globalPosition.Y;
		double result = Math.Atan2(x,y);
		result = result / 3.1415 * 180;
		if(result<0.0)
		{
			result += 360;
		}
		return result;
	}

    public void Player_Animation(double direction,Vector2I _moveDirection)
	{
		if(_moveDirection == Vector2I.Zero)
		{
			if(direction>=22.5&&direction<22.5+45)
		{_animatedSprite2D.Play("idle_rightdown");}
		else if(direction>=22.5+45&&direction<22.5+45*2)
		{_animatedSprite2D.Play("idle_right");}
		else if(direction>=22.5*2+45&&direction<22.5+45*3)
		{_animatedSprite2D.Play("idle_rightup");}
		else if(direction>=22.5*3+45&&direction<22.5+45*4)
		{_animatedSprite2D.Play("idle_up");}
		else if(direction>=22.5*4+45&&direction<22.5+45*5)
		{_animatedSprite2D.Play("idle_leftup");}
		else if(direction>=22.5*5+45&&direction<22.5+45*6)
		{_animatedSprite2D.Play("idle_left");}
		else if(direction>=22.5*6+45&&direction<22.5+45*7)
		{_animatedSprite2D.Play("idle_leftdown");}
		else
		{_animatedSprite2D.Play("idle_down");}
		}
		if(direction>=22.5&&direction<22.5+45)
		{_animatedSprite2D.Play("run_rightdown");}
		else if(direction>=22.5+45&&direction<22.5+45*2)
		{_animatedSprite2D.Play("run_right");}
		else if(direction>=22.5*2+45&&direction<22.5+45*3)
		{_animatedSprite2D.Play("run_rightup");}
		else if(direction>=22.5*3+45&&direction<22.5+45*4)
		{_animatedSprite2D.Play("run_up");}
		else if(direction>=22.5*4+45&&direction<22.5+45*5)
		{_animatedSprite2D.Play("run_leftup");}
		else if(direction>=22.5*5+45&&direction<22.5+45*6)
		{_animatedSprite2D.Play("run_left");}
		else if(direction>=22.5*6+45&&direction<22.5+45*7)
		{_animatedSprite2D.Play("run_leftdown");}
		else
		{_animatedSprite2D.Play("run_down");}
		
	}

	public Vector2I MoveInput()
	{
		var move_x = Input.GetActionStrength("right") - Input.GetActionStrength("left");
		var move_y = Input.GetActionStrength("down") - Input.GetActionStrength("up");
		var direction = new Vector2(move_x,move_y);
		return (Vector2I)direction.Sign();
	}

	public void DataInit()
	{
		_characterData.ACCELERATION = 50;
		_characterData.MAX_HEALTH = 100;
		_characterData.MAX_SPEED = 300;
		_characterData.tough = 100;
		_characterData.attack = 5;
		//_characterData.sight = 50;
		//_characterData.health = 10;
	}

	public bool Attack()
	{
		var _hitbox = _hitboxPosition.GetNode<Area2D>("Hitbox");
		var _collshape = _hitbox.GetNode<CollisionShape2D>("CollisionShape2D");
		//_collshape.Disabled = true;//获取hitbox碰撞

		if(_timer.TimeLeft ==0)
		{
			if(Input.IsActionJustPressed("leftmouse"))
			{
				_collshape.Disabled = false;//启用hitbox
				//GD.Print("鼠标点击",_collshape.Disabled,CharacterData.sight);
				var UIControl = GetNode<UIControl>("/root/UIControl");
				//UIControl.GetGuiViewManager().ShowTips("攻击");
				if(!this.HasNode("Punch"))
				{
					//_skillManager.GetNode<SkillPunch>("SkillPunch").SkillTocharacter(this,this);
					
				}
				_timer.Start(-0.1);//冷却时间
				return true;
			}
			if(Input.IsMouseButtonPressed(MouseButton.Right)&&_skillManager.GetChildCount() > 0)
			{
				SkillBase skill = _skillManager.GetChild(0) as SkillBase;
				skill.SkillToPosition(this,GetGlobalMousePosition());
			}
			
		}
		return false;

	}

	public override State GetNextState(int state)
	{
        _moveDirection = MoveInput();
		State _state = (State)state;
		if(Attack())
		{
			return State.ATTACK_LEFT;
		}
		switch (_state)
		{
			case State.IDLE: //idle
				if(_moveDirection != Vector2I.Zero)
				{
					return State.RUN;
				}
				break;
			case State.RUN: 
				if(_moveDirection == Vector2I.Zero)
				{
					return State.IDLE;
				}
				break;
			case State.ATTACK_LEFT:
				if(!_animationPlay._animated.IsPlaying())
				{
					return State.IDLE;
				}
				break;
			
		}
		return (State)state;
	}

    public override void StateChange(int from, int to)
    {
		State statefrom = (State)from;
		State stateto = (State)to;
        _moveDirection = MoveInput();
        
		switch (stateto)
		{
			case State.IDLE:
			{
                action = "idle";
				break;
			}
			case State.RUN:
			{
				action = "run";
                
				break;
			}
            case State.SKILL:
            {
                action = "attack";
                break;
            }
            case State.ATTACK_LEFT:
            {
                action = "attack";
				_skillManager.GetNode<SkillPunch>("SkillPunch").SkillTocharacter(this,this);
                break;
            }
		}
        
		var movedirection = MoveDirection();
		var _mouseposition= GetGlobalMousePosition();
		var direction = MouseDirection(_mouseposition);
		if(action ==""||action == null)
		{
			action = "idle";
		}
		if(action =="idle"||action == "attack")
		{
			movedirection = direction;
		}
		if(from == to&&stateto == State.ATTACK_LEFT)
		{
			return;
		}
		_animationPlay.Player_Animation(movedirection,action,8.0f);

		if(from != to)
		{
			GD.Print(this.Name,"[",statefrom,"]","==>","[",stateto,"]");
		}
    }


    public void OnTimerOut()
	{
		var _hitbox = _hitboxPosition.GetNode<Area2D>("Hitbox");
		var _collshape = _hitbox.GetNode<CollisionShape2D>("CollisionShape2D");
		_collshape.Disabled = true;//再次停用hitbox和计时器
		_timer.Stop();
	}

	public void register_interactable(Interactable v)
	{
		bool inthis = false;
		if(interacting_with != null)
		{
			foreach(Interactable interactable in interacting_with)
			{
				if(interactable == v)
				inthis = true;
				break;
			}
		}
		
		if (inthis)
		{return; }
		else
		{
			//GD.Print("注册交互物品");
			interacting_with.Add(v);

		}
	}
	public void  unregister_interactable(Interactable v)
	{
		interacting_with.Remove(v);
	}

	public override void AcceptTask(string taskName)
	{}

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

	
    public override Dictionary<string, Variant> GetDataForSave()
	{
		var playerDataForSave = base.GetDataForSave();
		var playerData = this.CharacterData as PlayerData;

		//后续添加物品和其他角色数据
		playerDataForSave.Add("LeftHand", playerData.LeftHand);
		playerDataForSave.Add("RightHand", playerData.RightHand);
		playerDataForSave.Add("TasksList", playerData.Inventory);
		playerDataForSave.Add("Inventory", playerData.Inventory);
		playerDataForSave.Add("Equipment", playerData.Equipment);
		playerDataForSave.Add("MapinHand",playerData.MapinHand);
		playerDataForSave.Add("Maps",playerData.Maps);


		return playerDataForSave;
	}

	public new bool InitializeByLoadData()
	{
		if(_saveLoadManager.LoadData ==null ||_saveLoadManager.LoadData.Count == 0 ||!_saveLoadManager.LoadData.ContainsKey("player"))
		{return false;}

		var player = _saveLoadManager.LoadData["player"].AsGodotDictionary<string,Variant>();

		(_characterData as PlayerData).LeftHand = player["LeftHand"].AsString();
		(_characterData as PlayerData).RightHand = player["RightHand"].AsString();
		(_characterData as PlayerData).MapinHand = player["MapinHand"].AsString();
		(_characterData as PlayerData).Inventory = player["Inventory"].AsGodotArray<string>();
		(_characterData as PlayerData).Inventory = player["TasksList"].AsGodotArray<string>();
		(_characterData as PlayerData).Equipment = player["Equipment"].AsGodotDictionary<string,string>();
		(_characterData as PlayerData).Maps = player["Maps"].AsGodotArray<string>();

		_cEquipment.Initialize();
		_cInventory.Initialize();
		
		return false;
	}

}
